package com.yixing.tech.wms.service.impl;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.CommonConstant;
import com.yixing.tech.common.entity.ErpRawInStock;
import com.yixing.tech.common.service.AbstractWmsService;
import com.yixing.tech.wms.service.ErpReportService;

import lombok.extern.slf4j.Slf4j;
import org.apache.axis.client.Call;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import java.rmi.RemoteException;
import java.util.*;

import static com.yixing.tech.common.CommonConstant.ERP_SET;


/**
 * @author yixing tech
 * @since 1.0.0
 */
@Slf4j
@Service
public class ErpReportServiceImpl extends AbstractWmsService implements ErpReportService {

    @Override
    public Object createPurInStock() throws BusinessException {
        ErpRawInStock erpRawInStock = ErpRawInStock.demo();
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
        String param = null;
        try {
            param = mapper.writeValueAsString(erpRawInStock);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return erpReport("CreatePurInStock", param, "CreatePurInStockReturn");
    }

    @Override
    public String erpReport(String method, String param, String returnQName) throws BusinessException {
        // 查询配置
        List<Document> sets = mongoTemplate.find(Query.query(newCriteria().and("enable").is(true)), Document.class, "entity_" + ERP_SET);
        if(CollectionUtils.isEmpty(sets)) {
            throw new BusinessException("Erp对接未配置");
        }
        String loginUrl = "", bizUrl = "";
        for (Document set : sets) {
            if("biz".equals(set.getString("type"))) {
                bizUrl = set.getString("url");
            } else if ("login".equals(set.getString("type"))) {
                loginUrl = set.getString("url");
            }
        }
        if(StringUtils.isBlank(loginUrl)) {
            throw new BusinessException("Erp登录地址未配置");
        }
        if(StringUtils.isBlank(bizUrl)) {
            throw new BusinessException("Erp业务地址未配置");
        }

        Call call;
        Document logDoc = new Document();
        try {
            call = erpLogin2(loginUrl);
        } catch (BusinessException e) {
            throw new RuntimeException(e);
        }

        call.setOperationName(method);
        String webServiceUrl = bizUrl;
        call.setTargetEndpointAddress(webServiceUrl);
        call.setReturnQName(new QName("", returnQName));
        call.setReturnType(new QName("urn:lang.java", "String"));
        call.setReturnClass(String.class);
        call.setTimeout(Integer.valueOf(1000 * 600000 * 60));
        call.setMaintainSession(true);
        call.addParameter("json", new QName("urn:lang.java", "String"), ParameterMode.IN);

        Object result = null;
        try {
            logDoc.put("路径", webServiceUrl + ": " + method);
            logDoc.put("createTime", new Date());
            logDoc.put("createName", "WMS");
            logDoc.put("tenantId", tenantId);
            logDoc.put("IP地址", getIp());
            logDoc.put("请求类型", "WebService");
            logDoc.put("类型", "三方");

            log.info("erp上报，方法:[{}] 参数:[{}]", method, param);
            result = call.invoke(new Object[]{param});

            logDoc.put("结果", result.toString());
        } catch (RemoteException e) {
            log.error("erp上报，方法:[{}] 参数:[{}]发生异常", method, param, e);
            logDoc.put("结果", String.format("异常: %s", e.getMessage()));
            throw new BusinessException("call#invoke() failed", e);
        } finally {
            mongoTemplate.insert(logDoc, "entity_" + CommonConstant.LOG_TABLE);
        }
        return String.valueOf(result);
    }

}
